﻿using System;
using System.Windows.Forms;
using DigitalRune.Windows.Docking;
using md.imi.membrane.common.Interfaces;
using md.imi.membrane.common.Messaging;
using md.imi.membranes.objects;

namespace md.imi.membranes.gui.Info
{
    public partial class LogsView : DockableForm, IMessageViewer
    {
        public object syncObject = new object();
        private static LogsView instance;

        public LogsView()
        {
            InitializeComponent();
            instance = this;
        }

        private void LogsView_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
        {
            instance = null;
        }

        public static void AddLogEntry(LogEntry logEntry)
        {
            if (logEntry == null)
            {
                return;
            }

            if (logEntry.MessageType == LogEntry.MsgType.Info)
            {
                Info("{0}", logEntry.Message);
            }
            else if (logEntry.MessageType == LogEntry.MsgType.Warning)
            {
                Warning("{0}", logEntry.Message);
            }
            else if (logEntry.MessageType == LogEntry.MsgType.Error)
            {
                Error("{0}", logEntry.Message);
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="format"></param>
        /// <param name="values"></param>
        public static void Info(string format, params  object[] values)
        {
            if (instance == null && instance.IsDisposed)
            {
                return;
            }

            lock (instance.syncObject)
            {
                instance.ShowSafeMessage(LogEntry.MsgType.Info, DateTime.Now, String.Format(format, values));
            }
        }

        public static void Warning(string format, params  object[] values)
        {
            if (instance == null && instance.IsDisposed)
            {
                return;
            }

            lock (instance.syncObject)
            {
                instance.ShowSafeMessage(LogEntry.MsgType.Warning, DateTime.Now, String.Format(format, values));
            }
        }

        public static void Error(string format, params  object[] values)
        {
            if (instance == null && instance.IsDisposed)
            {
                return;
            }

            lock (instance.syncObject)
            {
                instance.ShowSafeMessage(LogEntry.MsgType.Error, DateTime.Now, String.Format(format, values));
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="messageType"></param>
        /// <param name="date"></param>
        /// <param name="message"></param>
        private delegate void ShowSafeMessageDelegate(LogEntry.MsgType messageType, DateTime date, string message);

        private void ShowSafeMessage(LogEntry.MsgType messageType, DateTime date, string message)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new ShowSafeMessageDelegate(ShowSafeMessage), new object[] { messageType, date, message });
                return;
            }

            var listItem = new ListViewItem() { ImageIndex = (int)messageType };
            listItem.SubItems.Add(date.ToString());
            listItem.SubItems.Add(message);

            listView1.Items.Add(listItem);
        }

        public void AddMessage(MessageData message)
        {
            //TODO: Implement sending of a  log messages
            // throw new NotImplementedException();
            if (message == null || message.Data == null || 
                (message.Data is LogEntry) == false)
            {
                return;
            }
            var le = message.Data as LogEntry;

            ShowSafeMessage(le.MessageType, le.TimeStamp, le.Message);
        }

        public void ClearView()
        {
            // TODO: Implement
            //throw new NotImplementedException();
        }

        /// <summary>
        ///     Object specific destination type
        /// </summary>
        /// <returns></returns>
        public DestinationType GetDestinationType()
        {
            return DestinationType.LogsTarget;
        }

    }
}